<script lang="ts">
	import { userIdentity } from '$lib/AniList/identity.js';
	import { user } from '$lib/AniList/user.js';
	import type { Badge } from '$lib/userBadgesDatabase.js';
	import { domToBlob } from 'modern-screenshot';
	import { onMount } from 'svelte';
	// import { io } from 'socket.io-client';

	export let data;

	let editMode = false;
	let currentUserIdentity: ReturnType<typeof userIdentity>;
	let error: null | string;
	// const socket = io();
	let badges: Badge[] | null = null;
	let dark = true;
	let transparent = false;

	onMount(async () => {
		// socket.on('badges', (message) => (badges = message));

		badges = await (await fetch(`/api/badges?id=${(await user(data.username)).id}`)).json();

		if (data.user) {
			currentUserIdentity = userIdentity(data.user);

			// socket.emit('badges', data.user);
		} else {
			currentUserIdentity = new Promise((resolve) =>
				resolve({
					name: 'Guest',
					id: -1
				})
			);
		}
	});

	const submitBadge = () => {
		const imageURL = document.querySelector('input[name="image_url"]') as HTMLInputElement;
		const activityURL = document.querySelector('input[name="activity_url"]') as HTMLInputElement;
		const description = document.querySelector('input[name="description"]') as HTMLInputElement;

		if (!imageURL.value || !activityURL.value) {
			error = 'Fields cannot be empty.';

			return;
		}

		if (!imageURL.value.startsWith('http') || !activityURL.value.startsWith('http')) {
			error = 'URLs must start with http or https.';

			return;
		}

		fetch(
			`/api/badges?image=${encodeURIComponent(imageURL.value)}&post=${encodeURIComponent(
				activityURL.value
			)}&description=${encodeURIComponent(description.value)}`,
			{
				method: 'PUT'
			}
		).then(() => {
			error = null;
			imageURL.value = '';
			activityURL.value = '';
			description.value = '';
		});
	};

	const removeBadge = (badge: Badge) => {
		fetch(`/api/badges?id=${badge.id}`, {
			method: 'DELETE'
		}).then(() => {
			(document.querySelector(`#badge-${badge.id}`) as HTMLAnchorElement).style.display = 'none';
		});
	};

	const nbsp = (str: string) => str.replace(/ /g, '&nbsp;');

	const screenshot = async () => {
		let element = document.querySelector('#badges') as HTMLElement;

		element.classList.add('invert');

		if (element !== null) {
			domToBlob(element, {
				style: {
					backgroundColor: transparent ? 'transparent' : dark ? '#0b1622' : '#edf1f5'
				},
				quality: 1,
				scale: 2,
				fetch: {
					requestInit: {
						mode: 'cors'
					}
					// bypassingCache: true
				}
			}).then((blob) => {
				const downloadWrapper = document.createElement('a');
				const wrappedImageButton = document.getElementById(
					'wrapped-image-download'
				) as HTMLAnchorElement;
				const image = document.createElement('img');
				const object = (window.URL || window.webkitURL || window || {}).createObjectURL(blob);

				downloadWrapper.href = object;
				downloadWrapper.target = '_blank';
				image.src = object;

				downloadWrapper.appendChild(image);

				if (wrappedImageButton !== null) {
					wrappedImageButton.href = object;
				}

				const wrappedFinal = document.getElementById('wrapped-final');

				if (wrappedFinal !== null) {
					wrappedFinal.innerHTML = '';
					wrappedFinal.appendChild(downloadWrapper);
				}

				downloadWrapper.click();
			});

			await new Promise((resolve) => setTimeout(resolve, 1000));

			element.classList.remove('invert');
		}
	};
</script>

{#await currentUserIdentity}
	Loading ...
{:then identity}
	{@const isOwner = identity && identity.name === data.username}

	{#if isOwner}
		<p>
			<a href={`/user/${data.username}`}>Back to Profile</a>
			•
			<a href={`#`} on:click={() => (editMode = !editMode)}>
				{editMode ? 'Disable' : 'Enable'} Edit Mode
			</a>
			•
			<a href={`#`} on:click={() => screenshot()}>Download</a>
			•
			<input type="checkbox" bind:checked={dark} /> Dark Mode
			<input type="checkbox" bind:checked={transparent} /> Transparent Background
		</p>
	{/if}

	{#if editMode && isOwner}
		<p>
			Delete mode is enabled. Click on an image to delete it. There is no confirmation, so be
			careful!
		</p>

		{#if error}
			<p style="color: red;">{error}</p>
		{/if}

		<p>
			<input type="text" placeholder="Image URL" name="image_url" minlength="1" maxlength="1000" />
			<input
				type="text"
				placeholder="Activity URL"
				name="activity_url"
				minlength="1"
				maxlength="1000"
			/>
			<input
				type="text"
				placeholder="Description (Optional)"
				name="description"
				minlength="1"
				maxlength="1000"
			/>
			<a href={`#`} on:click={submitBadge}>Add Badge</a>
		</p>
	{/if}

	<div id="badges">
		{#if badges === null}
			{@html nbsp('Loading ...')}
		{:else if badges.length === 0}
			{@html nbsp('No badges found for this user.')}
		{:else}
			{#each badges as badge}
				{#if editMode}
					<a href={`#`} on:click={() => removeBadge(badge)} id={`badge-${badge.id}`}>
						<img src={badge.image} alt={badge.description} title={badge.description} />
					</a>
				{:else}
					<a href={badge.post} target="_blank" id={`badge-${badge.id}`}>
						<img src={badge.image} alt={badge.description} title={badge.description} />
					</a>
				{/if}
			{/each}
		{/if}
	</div>
{/await}

<style>
	/* body {
		margin: 0;
		padding: 0;
		text-align: center;
		background-color: #151f2e;
	} */

	img {
		width: 100%;
		height: auto;
	}

	#badges {
		display: grid;
		grid-template-columns: repeat(auto-fill, minmax(8%, 1fr));
		grid-gap: 0.25%;
	}

	:global(.invert *) {
		filter: invert(0) !important;
	}
</style>
